package com.szj.coroutine.project.jvm.blog6

import android.util.Log
import com.szj.coroutine.project.jvm.util.printlnJob
import com.szj.coroutine.project.jvm.util.printlnThread
import kotlinx.coroutines.*
import kotlin.coroutines.*
import kotlin.math.PI

/*
 * 作者: 史大拿
 * 时间: 2023/2/24$ 09:26$
 */

// todo ========================= 源码分析 ===============================
//fun main() {
//    val scope = CoroutineScope(EmptyCoroutineContext)
//
//    println("main start")
//    val interceptor = MyContinuationInterceptor()
//    scope.launch(interceptor) {
//        printlnThread("开启了一个协程1:${coroutineContext}")
//    }
//
//    println("main end")
//}
//private class MyContinuationInterceptor : ContinuationInterceptor {
//    override val key: CoroutineContext.Key<*>
//        get() = ContinuationInterceptor.Key
//
//    override fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T> {
//        println("拦截到了")
//        return continuation
//    }
//}


// todo ========================= 手动1 ===============================
//data class TestBean(val message: String)
//
//fun main() {
//    fun test(receiver: TestBean, block: suspend TestBean.() -> String) {
//        // TODO 创建协程
//        val continuation = block.createCoroutine(receiver, object : Continuation<String> {
//            override val context: CoroutineContext
//                get() = CoroutineName("手动开启协程") + Job() + Dispatchers.IO
//
//            override fun resumeWith(result: Result<String>) {
//                // 当协程恢复的时候执行
//                printlnThread("resume:$result")
//            }
//        })
//        val job = continuation.context[Job]!!.job
//        printlnJob("job0", job)
//        job.cancel()
//        printlnJob("job1", job)
//        if (!job.isCancelled) { // TODO 当Job取消后，就不恢复了
//            continuation.resume(Unit)
//        }
//        printlnJob("job2", job)
//    }
//
//    val bean = TestBean("测试数据")
//    test(bean) {
//        printlnThread("我是test内部方法${this}\t${coroutineContext}")
//        "我是返回数据"
//    }
//
//    Thread.sleep(1000)
//}


// todo ========================= 手动2 ===============================
//data class TestBean(val message: String)
//
//fun main() {
//    fun test(receiver: TestBean, block: suspend TestBean.() -> String) {
//        val coroutineExceptionHandler = CoroutineExceptionHandler { _, throwable ->
//            println("捕获到了异常:${throwable.message}")
//        }
//        // TODO 创建协程
//        val continuation = block.createCoroutine(receiver, object : Continuation<String> {
//            override val context: CoroutineContext
//                get() = CoroutineName("手动开启协程") + Job() + Dispatchers.IO + coroutineExceptionHandler
//
//            override fun resumeWith(result: Result<String>) {
//                result.onSuccess {
//                    printlnThread("success:$result")
//                }.onFailure {
//                    printlnThread("onFailure:${it.message}")
////                    result.getOrThrow() // 会throw异常
//                    throw it // self throw
//                }
//            }
//        })
//        continuation.resume(Unit)
//    }
//
//    val bean = TestBean("测试数据")
//    test(bean) {
//        printlnThread("我是test内部方法${this}")
//        throw RuntimeException("我是错误") // TODO throw异常
//        "我是返回数据"
//    }
//
//    Thread.sleep(1000)
//}

//
//// todo ========================= 手动3 ===============================
//fun main() {
//    val continuation = suspend {
//        println("我是suspend中的代码")
//        Thread.sleep(1000)
//        3.1415925f // 返回值
//    }.createCoroutine(object : Continuation<Float> {
//        override val context: CoroutineContext
//            get() = EmptyCoroutineContext
//
//        override fun resumeWith(result: Result<Float>) {
//            println("result:$result")
//        }
//    })
//
//    continuation.resume(Unit)// 恢复
//}


// todo ========================= 手动4 ===============================
fun main() {
    suspend {
        println("我是suspend中的代码")
        Thread.sleep(1000)
        3.1415925f // 返回值
    }.startCoroutine(object : Continuation<Float> { // TODO 直接创建并开启
        override val context: CoroutineContext
            get() = EmptyCoroutineContext

        override fun resumeWith(result: Result<Float>) {
            println("result:$result")
        }
    })

}